﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading;
using Justin.Log;
using Justin.Stock.DAL;
using Justin.FrameWork.Extensions;
using Justin.Stock.Entities;
namespace Justin.Stock.Models
{

    [Serializable]
    public delegate void EventHandler<JEventArgs>(object sender, JEventArgs e) where JEventArgs : EventArgs;
    public class StockService
    {
        private static IRequest iRequest;
        public static bool ForceDownLoadAllStock = false;
        public static bool ResetMyStock = false;
        public static int ReDoSecond = 5;

        public static EventHandler<StockEventArgs> ProcessEvent { get; set; }       
        private static object syncMyStockData = new Object();
        private static object syncRequest = new Object();
        static System.Timers.Timer timer;

        static StockService()
        {
            timer = new System.Timers.Timer(ReDoSecond * 1000);
            timer.Elapsed += new System.Timers.ElapsedEventHandler(Time_Tick);
            timer.AutoReset = true;
            timer.Enabled = true;
            iRequest = RequestFactory.GetRequest((DataSource)(ConfigurationManager.AppSettings["MonitorSite"].Value<int>()));
        }

        #region 自选股

        private static List<StockInfo> myStock = null;
        public static List<StockInfo> MyStock
        {
            get
            {
                lock (syncMyStockData)
                {
                    if (myStock == null || ResetMyStock)
                    {
                        myStock = new StockDAL().getAllMyStock();
                        if (ResetMyStock)
                        {
                            ResetMyStock = false;
                        }
                    }

                    return myStock;
                }

            }
        }

        #endregion

        #region 刷新股票信息
        
        private static bool RefreshDataBeyondTime = false;
        private static void Time_Tick(object source, System.Timers.ElapsedEventArgs e)
        {
            if (CheckTimeIsOpen())
            {
                RefreshStockDataFromSina();
            }
            else
            {
                if (!RefreshDataBeyondTime)
                {
                    RefreshStockDataFromSina();
                    RefreshDataBeyondTime = true;
                }
            }
        }
        private static void RefreshStockDataFromSina()
        {
            try
            {
                if (ProcessEvent.GetInvocationList().Count() > 0)
                {
                    lock (syncRequest)
                    {
                        List<StockInfo> StockDatas = MyStock;
                        if (StockDatas != null && StockDatas.Count > 0)
                        {
                            iRequest.RefreshStockData(StockDatas);
                            OnStockDataChanged(new StockEventArgs(StockDatas));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                JLog.Write(LogMode.Error, ex);
            }

        }
        protected static void OnStockDataChanged(StockEventArgs e)
        {
            if (ProcessEvent != null)
            {
                foreach (EventHandler<StockEventArgs> stockEvent in ProcessEvent.GetInvocationList())
                {
                    stockEvent(null, e);
                }
            }
        }

        #endregion

        #region 股票代码名称大全

        private static List<Tuple<string, string, string>> _allStocks = null;
        private static List<Tuple<string, string, string>> GetAllStocks()
        {
            IRequest allStockRequest = RequestFactory.GetRequest(DataSource.EastMoney);
            return allStockRequest.GetAllStocks();
        }
        /// <summary>
        /// item1：Code Item2:no,Item3:Name
        /// </summary>
        public static List<Tuple<string, string, string>> AllStocks
        {
            get
            {
                if (_allStocks == null || ForceDownLoadAllStock)
                {
                    _allStocks = GetAllStocks();
                    if (ForceDownLoadAllStock)
                    {
                        ForceDownLoadAllStock = false;
                    }
                }
                return _allStocks;
            }

        }

        #endregion

        public static void AddEvent(EventHandler<StockEventArgs> value)
        {
            if (ProcessEvent != null)
            {
                if (!ProcessEvent.GetInvocationList().Select(row => row.Method.Name).Contains(value.Method.Name))
                {
                    ProcessEvent += value;
                }
            }
            else
            {
                ProcessEvent += value;
            }
        }
        public static void RemoveEvent(EventHandler<StockEventArgs> value)
        {
            if (ProcessEvent != null)
            {
                if (ProcessEvent.GetInvocationList().Select(row => row.Method.Name).Contains(value.Method.Name))
                {
                    ProcessEvent -= value;
                }
            }
        }

        #region 启动、停止、重启

        public static void Start(int second = 0)
        {
            if (second != 0)
            {
                timer.Interval = second * 1000;
            }
            timer.Enabled = true;
        }
        public static void ReStart(int second = 0)
        {
            timer.Enabled = false;
            if (second != 0)
            {
                timer.Interval = second * 1000;
            }
            Thread.Sleep(1000);
            timer.Enabled = true;
        }
        public static void Stop()
        {
            timer.Enabled = false;
        }

        #endregion
               
        private static bool CheckTimeIsOpen()
        {
            if (!Constants.CheckTime)
            {
                return true;
            }
            DateTime now = DateTime.Now;

            DateTime firstOpenTime = new DateTime(now.Year, now.Month, now.Day, 9, 0, 0);
            DateTime firstCloseTime = new DateTime(now.Year, now.Month, now.Day, 11, 35, 0);

            DateTime secondOpenTime = new DateTime(now.Year, now.Month, now.Day, 12, 55, 0);
            DateTime secondCloseTime = new DateTime(now.Year, now.Month, now.Day, 15, 05, 0);

            if (now > firstOpenTime && now < firstCloseTime)
            {
                return true;
            }
            if (now > secondOpenTime && now < secondCloseTime)
            {
                return true;
            }
            return false;
        }
        


    }
}
